// 单个最小实例单元 
module onehot_unit_2(
input     i0        ,
input     i1        ,
output    is_onehot ,// 1 means already has onehot, so the others must be 0
output    not_onehot // 1 means 100% not onehot, noneed to check others
);

wire i0_inv;  not u_i0_inv (i0_inv,i0);
wire i0_and;  and u_i0_and (i0_and,i0_inv,i1);

wire i1_inv;  not u_i1_inv (i1_inv,i1);
wire i1_and;  and u_i1_and (i1_and,i1_inv,i0);

or u_is_onehot(is_onehot,i0_and,i1_and);

and u_not_onehot(not_onehot,i0,i1);

endmodule

// 可级联的实例单元 
module onehot_unit_2plus(
input     i_cur           ,
input     i_is_onehot_pre ,
input     i_not_onehot_pre,
output    o_is_onehot_cur ,
output    o_not_onehot     
);

wire tmp_is_onehot; wire tmp_not_onehot;
// 调用单个最小实例单元
onehot_unit_2 u_unit2(.i0(i_is_onehot_pre),.i1(i_cur),.is_onehot(o_is_onehot_cur),.not_onehot(tmp_not_onehot));

or u_not_onehot(o_not_onehot,i_not_onehot_pre,tmp_not_onehot);

);
endmodule


module onehot_unit #(parameter N=10)(
input [N-1:0] din      ,
output        is_onehot
);

//可以任意位数调用实例单元，但是要求N>=2,
//对于1位输入，独热码的讨论没有实际意义
wire [N-2:0]tmp_din;
genvar i;
for (i=0;i<N-1;  i=i+1)begin 
  //考虑第0级的调用，它的pre级都是0
  if(i==0)begin
    onehot_unit_2plus U_unit0(
      .i_cur            (din[0]             ),
      .i_is_onehot_pre  (1'b0               ),
      .i_not_onehot_pre (1'b0               ),
      .o_is_onehot_cur  (tmp_din[0]         ),
      .o_not_onehot     (tmp_not_onehot[0]  )
    );
  end
  else begin
  //后面的级数可以递归串联调用
    onehot_unit_2plus U_unitN(
      .i_cur            (din[i]              ),
      .i_is_onehot_pre  (tmp_din[i-1]        ),
      .i_not_onehot_pre (tmp_not_onehot[i-1] ),
      .o_is_onehot_cur  (tmp_din[i]          ),
      .o_not_onehot      (tmp_not_onehot[i]  )
    );
  end
end

//最后考虑只有tmp_not_onehot信号不生效，且最新的onehot即tmp_din[N-1]生效后，才
//认为是真实的one hot
assign is_onehot = ~tmp_not_onehot[N-1] && tmp_din[N-1];

endmodule



